using System;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Net;
using OpenWaves.ActivityFeed.Web.Handler;

namespace OpenWaves.ActivityFeed.Web.Modules
{
    public class CommentsModule : RestModule
    {
        public CommentsModule(IActivityFeedService activityFeedService, IUserIdentityProvider identityProvider, IUserProfileProvider userProfileProvider)
        {
            Contract.Requires<ArgumentNullException>(activityFeedService != null);
            Contract.Requires<ArgumentNullException>(userProfileProvider != null);

            this.Post("/activityFeed/updates/{updateId}/comments", (request, p) => 
                                                       {
                                                           string updateId = p["updateId"];
                                                           Contract.Assert(String.IsNullOrEmpty(updateId) == false);

                                                           var dto = request.DeserializeBody<CommentDto>();
                                                           Contract.Assert(String.IsNullOrEmpty(dto.Text) == false);

                                                           Update update = activityFeedService.GetUpdate(Url.Decode(updateId));
                                                           if (update == null)
                                                               return new HttpResult(HttpStatusCode.NotFound);

                                                           var comment = update.AddComment(dto.Text, identityProvider.Identity.Name);

                                                           return new JsonResult(Result.Ok(CommentDto.FromComment(comment, userProfileProvider)));
                                                       });

            this.Delete("/activityFeed/updates/{updateId}/comments/{commentId}", (request, p) => 
                                                                     {
                                                                         string updateId = p["updateId"];
                                                                         string commentId = p["commentId"];
                                                                         Contract.Assert(String.IsNullOrEmpty(updateId) == false);
                                                                         Contract.Assert(String.IsNullOrEmpty(commentId) == false);

                                                                         var currentUserId = identityProvider.Identity.Name;

                                                                         Update update = activityFeedService.GetUpdate(Url.Decode(updateId));
                                                                         if (update == null)
                                                                             return new HttpResult(HttpStatusCode.NotFound);

                                                                         var comment = update.Comments.SingleOrDefault(c => c.Id == Url.Decode(commentId));
                                                                         if (comment == null)
                                                                             return new HttpResult(HttpStatusCode.NotFound);

                                                                         if (comment.CanBeRemovedBy(currentUserId) == false)
                                                                             return new HttpResult(HttpStatusCode.Forbidden);

                                                                         update.RemoveComment(comment);

                                                                         return new JsonResult(Result.Ok());
                                                                     });
        }
    }
}